#define NANOPRINTF_CONVERSION_BUFFER_SIZE    512
#define NANOPRINTF_CONVERSION_FLOAT_TYPE    uint8_t

#include "unit_ftoa_rev.cc"

TEST_CASE("ftoa_rev_08") {
  memset(&spec, 0, sizeof(spec));

  SUBCASE("integer overflow") {
    spec.prec = 1;
    require_ftoa_rev("255.5", (npf_ftoa_man_t)-1 + 0.5);
    require_ftoa_rev("256.0", (npf_ftoa_man_t)-1 + 0.96875);
    require_ftoa_rev("260.0", (npf_ftoa_man_t)-1 + 1.);
    require_ftoa_rev("260.0", (npf_ftoa_man_t)-1 + 1.5);
    require_ftoa_rev("260.0", (npf_ftoa_man_t)-1 + 9.);
    require_ftoa_rev("270.0", (npf_ftoa_man_t)-1 + 10.);
  }

  SUBCASE("fraction accuracy") {
    spec.prec = 22 + 3;
    require_ftoa_rev("1.0312500000000000000000000", 1. + 1. / ((npf_double_bin_t)0x1 << (NPF_FTOA_MAN_BITS - 3)));
    require_ftoa_rev("0.9687500000000000000000000", 1. - 1. / ((npf_double_bin_t)0x1 << (NPF_FTOA_MAN_BITS - 3)));
    require_ftoa_rev("0.6687500000000000000000000", 2. / 3.);
    require_ftoa_rev("0.0000000000000000000006188", 2. / 3. / 1e21);
  }

  SUBCASE("limits") {
    // largest representable number
    require_ftoa_rev_bin(
      "16200000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000",
      ((npf_double_bin_t)NPF_DOUBLE_EXP_MASK << NPF_DOUBLE_MAN_BITS) - 1);

    spec.prec = 315 + 3;

    // smallest normal number
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000009875000000",
      (npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS);

    // largest subnormal number
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000009875000000",
      ((npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS) - 1);

    // smallest representable numbers
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000125000000",
      (npf_double_bin_t)0x3 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));

    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000077500000",
      (npf_double_bin_t)0x2 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));

    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000046875000",
      (npf_double_bin_t)0x1 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));
  }
}
